﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Security;
using System.DirectoryServices;

//////////////////////////////////////////////////////////////////////////
//Default.aspx.cs                                                       //
//Last Edited: 23 Mar 2012                                              //
//                                                                      //
//The default entry and login page. Authenticates against the Active    //
//  Directory server using the Lightweight Directory Access Protocol,   //
//  or LDAP.                                                            //
//Using code modified from a Microsoft tutorial:                        //
//http://msdn.microsoft.com/en-us/library/ff649227.aspx                 //
//////////////////////////////////////////////////////////////////////////
public partial class _Default : System.Web.UI.Page
{
    //////////////////////
    //Instance Variables//
    //////////////////////
    protected const String _domain = "CAMPUS"; //Domain for UP users

    //////////////////
    //Page Functions//
    //////////////////

    /// <summary>
    /// Page_Load()
    /// 
    /// Initializes the page.
    /// </summary>
    /// <param name="sender">object sender (unused, required by ASP.NET) - web control that called the function</param>
    /// <param name="e">EventArgs e (unused, required by ASP.NET) - other arguments for the function</param>
    protected void Page_Load(object sender, EventArgs e)
    {
        //Check cookies - If already authenticated, redirect appropriately
        if (Request.Cookies.Get(FormsAuthentication.FormsCookieName) != null)
        {
            try
            {
                //Decrypt cookie, pulling necessary information
                String encryptedTicket = Request.Cookies.Get(FormsAuthentication.FormsCookieName).Value;
                FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(encryptedTicket);
                String userName = authTicket.Name;
                //Redirect the user to the correct page
                Response.Redirect(DetermineRedirect(userName));
            }
            catch (Exception ex)
            {
                //Ignore all exceptions other than those related to authentication
                if (ex is LdapAuthentication.AuthenticationException)
                {
                    //Remove faulty cookies
                    FormsAuthentication.SignOut();
                    //Report errors
                    LoginFailureLabel.Text = ex.Message;
                }
            }
        }
        //If user has been redirected here due to a logout, display successful logout on page
        String value = Request.QueryString["logout"];
        if (value == null) return;
        LogoutSuccessLabel.Text = "You have been logged out successfully!";
    } //end Page_Load()

    /// <summary>
    /// LoginBox_Authenticate()
    /// 
    /// Called when the user clicks the login button.
    /// </summary>
    /// <param name="sender">object sender (unused, required by ASP.NET) - web control that called the function</param>
    /// <param name="e">EventArgs e (unused, required by ASP.NET) - other arguments for the function</param>
    protected void LoginBox_Authenticate(object sender, EventArgs e)
    {
        //Clear logout label
        LogoutSuccessLabel.Text = "";
        //Active Directory path - authenticate against this
        String adPath = "LDAP://campus.up.edu/DC=campus,DC=up,DC=edu";
        LdapAuthentication adAuth = new LdapAuthentication(adPath);
        try
        {
            //Determine where user will be redirected, throwing an exception if user doesn't have access
            String redirectLocation = DetermineRedirect(LoginNameBox.Text);
            //Try to authenticate
            if (adAuth.IsAuthenticated(_domain, LoginNameBox.Text, LoginPassBox.Text))
            {
                //Retrieve the user's groups
                String groups = adAuth.GetGroups();
                //Create the authetication ticket
                FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1, LoginNameBox.Text, DateTime.Now, DateTime.Now.AddMinutes(60), false, groups);
                //Encrypt and create a cookie
                String encryptedTicket = FormsAuthentication.Encrypt(authTicket);
                HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
                //Add the cookie to the browser's collection, expiring in 60 minutes
                authCookie.Expires = DateTime.Now.AddMinutes(60);
                Response.Cookies.Add(authCookie);

                //Redirect the user to the correct page
                Response.Redirect(redirectLocation);
            }
            else
            {
                //Notify user if authentication fails
                //NOTE: Due to checks and exceptions thrown by DetermineRedirect and isAuthenticated,
                //      this should never happen.
                throw new LdapAuthentication.AuthenticationException("Authentication failed, check username and password.");
            }
        }
        catch (Exception ex)
        {
            //Report if any error occurs
            LoginFailureLabel.Text = ex.Message;
        }
    } //end LoginBox_Authenticate()

    /////////////////////
    //Private Functions//
    /////////////////////

    /// <summary>
    /// DetermineRedirect()
    /// Throws AuthenticationException
    /// 
    /// Determines the user's level and redirects appropriately.
    /// Throws an AuthenticationException if user does not have access to application.
    /// </summary>
    /// <param name="sender">object sender (unused, required by ASP.NET) - web control that called the function</param>
    /// <param name="e">EventArgs e (unused, required by ASP.NET) - other arguments for the function</param>
    private String DetermineRedirect(String username)
    {
        //Determine user level and return appropriately
        SharedFunctions.UserLevel ul = SharedFunctions.getUserLevel(username);
        if (ul.Equals(SharedFunctions.UserLevel.ADVISEE))
        {
            return "~/Advisee/Default.aspx";
        }
        else if (ul.Equals(SharedFunctions.UserLevel.ADVISOR) || ul.Equals(SharedFunctions.UserLevel.ADMIN))
        {
            return "~/Advisor/Default.aspx";
        }
        else
        {
            throw new LdapAuthentication.AuthenticationException("Sorry, you do not have access to this application.");
        }
    }
}